﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using Taoyl.CodeTraceBLL;
using Taoyl.CodeTraceHelper;
using Taoyl.CodeTraceModels;
using xbd.NodeSettings;
using xbd.NodeSettings.CFG;

namespace Taoyl.CodeTracePro
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();

            this.updateTimer.Interval = 500;
            updateTimer.Tick += UpdateTimer_Tick;

            this.Load += FrmMain_Load;
            this.FormClosing += FrmMain_FormClosing;
        }

        private void UpdateTimer_Tick(object sender, EventArgs e)
        {
            this.UpdateMonitor?.Invoke();
            this.UpdateBoard?.Invoke();
        }



        //创建配置文件路径
        private string A1A2Path = Application.StartupPath + "\\Config\\A1A2";
        private string A3A4Path = Application.StartupPath + "\\Config\\A3A4";
        private string A5A6Path = Application.StartupPath + "\\Config\\A5A6";
        private string SysInfoPath = Application.StartupPath + "\\Config\\SysInfo.ini";

        private Color selectedColor = Color.FromArgb(36, 158, 153);
        private Color unSelectedColor = Color.Transparent;

        private System.Windows.Forms.Timer updateTimer = new System.Windows.Forms.Timer();

        //创建委托对象
        public Action UpdateMonitor;
        public Action UpdateBoard;
        private Action<MelsecDevice, string, bool> A1A2Handle;
        private Action<SiemensDevice, string, bool> A3A4Handle;
        private Action<ModbusTCPDevice, string, bool> A5A6Handle;
        private Func<List<CodeRecord>> GetCodeRecord;

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (new FrmMsgWithAck("是否确定退出系统", "退出系统").ShowDialog() == DialogResult.OK)
            {
                Global.A1A2.ForEach(c => c.Stop());
                Global.A3A4.ForEach(c => c.Stop());
                Global.A5A6.ForEach(c => c.Stop());

                //如果为了防止软件异常关闭，可以添加此操作
                Global.SysInfo.CurrentRecord = this.GetCodeRecord?.Invoke();
                SysInfoManager.SaveSysInfo(Global.SysInfo, this.SysInfoPath);

            }
            else
            {
                e.Cancel = true;
            }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            LogHelper.Info("程序开始运行");
            //A1A2
            var result1 = MelsecCFG.LoadDevice(A1A2Path);
            if (result1.IsSuccess)
            {
                Global.A1A2 = result1.Content;
                Global.A1A2.ForEach(c => c.Start());
                Global.A1A2.ForEach(c => c.AlarmEvent += PLC_AlarmEvent);
            }
            else
            {
                //弹窗
                new FrmMsgNoAck("A1A2设备配置解析失败:" + result1.Message, "配置文件").ShowDialog();
                return;
            }

            //A3A4
            var result2 = SiemensCFG.LoadDevice(A3A4Path);
            if (result2.IsSuccess)
            {
                Global.A3A4 = result2.Content;

                Global.A3A4.ForEach(c => c.Start());
                Global.A3A4.ForEach(c => c.AlarmEvent += PLC_AlarmEvent);
            }
            else
            {
                //弹窗
                new FrmMsgNoAck("A3A4设备配置解析失败:" + result2.Message, "配置文件").ShowDialog();
                return;
            }

            //A5A6
            var result3 = ModbusTCPCFG.LoadDevice(A5A6Path);
            if (result3.IsSuccess)
            {
                Global.A5A6 = result3.Content;
                Global.A5A6.ForEach(c => c.DataFormat = xbd.DataConvertLib.DataFormat.CDAB);
                Global.A5A6[0].Start();
                //Global.A5A6.ForEach(c => c.Start());
                //Global.A5A6.ForEach(c => c.AlarmEvent += PLC_AlarmEvent);
            }
            else
            {
                //弹窗
                new FrmMsgNoAck("A5A6设备配置解析失败:" + result3.Message, "配置文件").ShowDialog();
                return;
            }

            //读取配置文件
            var result = SysInfoManager.LoadSysInfo(this.SysInfoPath);
            if (result.IsSuccess)
            {
                Global.SysInfo = result.Content;
            }
            else
            {
                //弹窗
                new FrmMsgNoAck("读取配置文件解析失败:" + result.Message, "读取配置").ShowDialog();
                return;
            }

            //开启定时器
            updateTimer.Enabled = true;

            this.Common_Navi_Click(this.btn_Board, null);

            //打开默认界面
            this.Common_Navi_Click(this.btn_Monitor, null);

        }

        /// <summary>
        /// 业务处理
        /// </summary>
        /// <param name="variable"></param>
        /// <param name="e"></param>
        private void PLC_AlarmEvent(VariableBase variable, AlarmEventArgs e)
        {
            //检查触发
            if (e.IsTriggered)
            {
                if (e.VarName == "完成信号")
                {
                    if (e.CurrentValue == "1")
                    {
                        switch (e.DeviceName)
                        {
                            case "机台A1":
                            case "机台A2":
                                var device1 = Global.A1A2.Where(c => c.DeviceName == e.DeviceName).FirstOrDefault();
                                if (device1 != null)
                                {
                                    string code = device1["电机条码"]?.ToString();
                                    LogHelper.Debug($"收到完成信号:{e.DeviceName}:条码:{code}");
                                    if (code.Length > 0)
                                    {
                                        bool result = device1["检测结果"]?.ToString() == "1";

                                        //设备对象 条码 结果 给FrmMonitor去处理
                                        //委托
                                        this.A1A2Handle?.Invoke(device1, code, result);


                                        var write = device1.Write("完成信号", "0");

                                        if (write.IsSuccess)
                                        {
                                            LogHelper.Debug($"复位完成信号成功:{e.DeviceName},条码:{code}");
                                        }
                                        else
                                        {
                                            LogHelper.Debug($"复位完成信号失败:{e.DeviceName},条码:{code},{write.Message}");
                                        }

                                    }
                                    else
                                    {
                                        LogHelper.Debug($"{e.DeviceName}:条码为空");
                                    }
                                }
                                else
                                {
                                    LogHelper.Debug($"{e.DeviceName}:未找到指定PLC对象");
                                }
                                break;
                            case "机台A3":
                            case "机台A4":
                                var device2 = Global.A3A4.Where(c => c.DeviceName == e.DeviceName).FirstOrDefault();
                                if (device2 != null)
                                {
                                    string code = device2["电机条码"]?.ToString();
                                    LogHelper.Debug($"收到完成信号:{e.DeviceName}:条码:{code}");
                                    if (code.Length > 0)
                                    {
                                        bool result = device2["检测结果"]?.ToString() == "1";

                                        //设备对象 条码 结果 给FrmMonitor去处理
                                        //委托
                                        this.A3A4Handle?.Invoke(device2, code, result);


                                        var write = device2.Write("完成信号", "0");

                                        if (write.IsSuccess)
                                        {
                                            LogHelper.Debug($"复位完成信号成功:{e.DeviceName},条码:{code}");
                                        }
                                        else
                                        {
                                            LogHelper.Debug($"复位完成信号失败:{e.DeviceName},条码:{code},{write.Message}");
                                        }

                                    }
                                    else
                                    {
                                        LogHelper.Debug($"{e.DeviceName}:条码为空");
                                    }
                                }
                                else
                                {
                                    LogHelper.Debug($"{e.DeviceName}:未找到指定PLC对象");
                                }
                                break;
                            case "机台A5":
                            case "机台A6":
                                var device3 = Global.A5A6.Where(c => c.DeviceName == e.DeviceName).FirstOrDefault();
                                if (device3 != null)
                                {
                                    string code = device3["电机条码"]?.ToString();
                                    LogHelper.Debug($"收到完成信号:{e.DeviceName}:条码:{code}");
                                    if (code.Length > 0)
                                    {
                                        bool result = device3["检测结果"]?.ToString() == "1";

                                        //设备对象 条码 结果 给FrmMonitor去处理
                                        //委托
                                        this.A5A6Handle?.Invoke(device3, code, result);


                                        var write = device3.Write("完成信号", "0");

                                        if (write.IsSuccess)
                                        {
                                            LogHelper.Debug($"复位完成信号成功:{e.DeviceName},条码:{code}");
                                        }
                                        else
                                        {
                                            LogHelper.Debug($"复位完成信号失败:{e.DeviceName},条码:{code},{write.Message}");
                                        }

                                    }
                                    else
                                    {
                                        LogHelper.Debug($"{e.DeviceName}:条码为空");
                                    }
                                }
                                else
                                {
                                    LogHelper.Debug($"{e.DeviceName}:未找到指定PLC对象");
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }

        #region 窗体切换


        private void Common_Navi_Click(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                if (Enum.IsDefined(typeof(FormNames), btn.Text))
                {
                    FormNames formNames = (FormNames)Enum.Parse(typeof(FormNames), btn.Text);

                    if (OpenForm(formNames))
                    {
                        SetNaviButton(formNames);
                    }

                }
            }
        }

        private void SetNaviButton(FormNames formNames)
        {
            foreach (var btn in this.TopPanel.Controls.OfType<Button>())
            {
                if (Enum.IsDefined(typeof(FormNames), btn.Text))
                {
                    FormNames btnNames = (FormNames)Enum.Parse(typeof(FormNames), btn.Text);

                    if (btnNames == formNames)
                    {
                        btn.BackColor = Color.FromArgb(36, 158, 153);
                    }
                    else
                    {
                        btn.BackColor = Color.Transparent;
                    }

                }
            }
        }

        private bool OpenForm(FormNames formNames)
        {
            int total = this.MainPanel.Controls.Count;
            int closeCount = 0;
            bool isFind = false;

            for (int i = 0; i < total; i++)
            {
                Control ct = this.MainPanel.Controls[i - closeCount];

                if (ct is Form frm)
                {
                    //判断是否是我们需要的窗体

                    //如果是我们需要的窗体
                    if (frm.Text == formNames.ToString())
                    {
                        //置顶
                        frm.BringToFront();
                        isFind = true;
                        break;
                    }
                    //如果不是，判断是否为固定窗体
                    else if ((FormNames)Enum.Parse(typeof(FormNames), frm.Text) >= FormNames.临界窗体)
                    {
                        frm.Close();
                        closeCount++;
                    }
                }
            }

            if (isFind == false)
            {
                Form frm = null;

                switch (formNames)
                {
                    case FormNames.生产监控:
                        frm = new FrmMonitor();
                        this.UpdateMonitor = ((FrmMonitor)frm).UpdateMonitor;
                        this.A1A2Handle = ((FrmMonitor)frm).A1A2Handle;
                        this.A3A4Handle = ((FrmMonitor)frm).A3A4Handle;
                        this.A5A6Handle = ((FrmMonitor)frm).A5A6Handle;
                        this.GetCodeRecord = ((FrmMonitor)frm).GetCodeRecord;
                        break;
                    case FormNames.生产看板:
                        frm = new FrmBoard();
                        this.UpdateBoard = ((FrmBoard)frm).UpdateBoard;
                        Global.ProductCompletedHandle = ((FrmBoard)frm).ProductCompletedHandle;
                        break;
                    case FormNames.条码追溯:
                        frm = new FrmRecord();
                        break;
                    case FormNames.调试窗体:
                        frm = new FrmTest();
                        break;
                    default:
                        break;
                }

                if (frm != null)
                {
                    //非顶层窗体
                    frm.TopLevel = false;
                    //设置为无边框
                    frm.FormBorderStyle = FormBorderStyle.None;
                    //设置Dock
                    frm.Dock = DockStyle.Fill;
                    //设置父容器
                    frm.Parent = this.MainPanel;
                    //置顶
                    frm.BringToFront();
                    //显示
                    frm.Show();
                }
            }
            return true;
        }

        private void btn_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #endregion

        #region 无边框拖动 

        private Point mPoint;
        private void Panel_MouseDown(object sender, MouseEventArgs e)
        {
            mPoint = new Point(e.X, e.Y);
        }

        private void Panel_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Location = new Point(this.Location.X + e.X - mPoint.X, this.Location.Y + e.Y - mPoint.Y);
            }
        }
        #endregion

        /// <summary>
        /// 调试窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lbl_Test_DoubleClick(object sender, EventArgs e)
        {
            OpenForm(FormNames.调试窗体);
        }
    }
}
